#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(slot_timeout()));

    timer->start(100);
    ui->start_station->addItem("1");
    ui->start_station->addItem("2");
    ui->end_station->addItem("1");
    ui->end_station->addItem("2");

    is_setenabel_no();
}

void Widget::is_setenabel_no(){
    ui->state_label_3->setText("");
    ui->disconnect_pushButton->setEnabled(false);
    ui->connect_pushButton->setEnabled(false);
    ui->del_button->setEnabled(false);
    ui->clear_button->setEnabled(false);
    ui->up_button->setEnabled(false);
    ui->down_button->setEnabled(false);
    ui->left_button->setEnabled(false);
    ui->right_button->setEnabled(false);
    ui->start_ctrl_move->setEnabled(false);
    ui->stop_ctrl_move->setEnabled(false);
    ui->start_station->setEnabled(false);
    ui->station_move->setEnabled(false);
    ui->end_station->setEnabled(false);
    ui->charge->setEnabled(false);
    ui->stop_charge->setEnabled(false);
    ui->local->setEnabled(false);
    ui->stop_local->setEnabled(false);
    ui->cancel_button->setEnabled(false);
    ui->continue_button->setEnabled(false);
    ui->pause_button->setEnabled(false);
}

void Widget::is_setenabel_yes(){
    ui->connect_pushButton->setEnabled(true);
    ui->del_button->setEnabled(true);
    ui->clear_button->setEnabled(true);
    connect_state = get_agv_state();
    if (connect_state)
    {
        ui->start_station->setEnabled(true);
        ui->station_move->setEnabled(true);
        ui->end_station->setEnabled(true);
        ui->cancel_button->setEnabled(true);
        ui->continue_button->setEnabled(true);
        ui->pause_button->setEnabled(true);

        if (hand_ctrl_move){
            ui->up_button->setEnabled(true);
            ui->down_button->setEnabled(true);
            ui->left_button->setEnabled(true);
            ui->right_button->setEnabled(true);
            ui->start_ctrl_move->setEnabled(false);
            ui->stop_ctrl_move->setEnabled(true);
        }
        else {
            ui->up_button->setEnabled(false);
            ui->down_button->setEnabled(false);
            ui->left_button->setEnabled(false);
            ui->right_button->setEnabled(false);
            ui->start_ctrl_move->setEnabled(true);
            ui->stop_ctrl_move->setEnabled(false);
        }

        if (is_charge) {
            ui->charge->setEnabled(true);
            ui->stop_charge->setEnabled(false);
        }
        else {
            ui->charge->setEnabled(false);
            ui->stop_charge->setEnabled(true);
        }

        if (is_local) {
            ui->local->setEnabled(true);
            ui->stop_local->setEnabled(false);
        }
        else {
            ui->local->setEnabled(false);
            ui->stop_local->setEnabled(true);
        }
    }
    else {
        ui->start_station->setEnabled(false);
        ui->station_move->setEnabled(false);
        ui->end_station->setEnabled(false);
        ui->cancel_button->setEnabled(false);
        ui->continue_button->setEnabled(false);
        ui->pause_button->setEnabled(false);
        ui->up_button->setEnabled(false);
        ui->down_button->setEnabled(false);
        ui->left_button->setEnabled(false);
        ui->right_button->setEnabled(false);
        ui->start_ctrl_move->setEnabled(false);
        ui->stop_ctrl_move->setEnabled(false);

        ui->charge->setEnabled(false);
        ui->stop_charge->setEnabled(false);
        ui->local->setEnabled(false);
        ui->stop_local->setEnabled(false);
    }

}


void Widget::slot_timeout(void)
{
    ui->time_label->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd")+" "+QTime::currentTime().toString("hh:mm"));

    QString agv_name = ui->agv_comboBox->currentText();



    if (client_map.count() > 0) {
        is_setenabel_yes();
    }
    else {
        is_setenabel_no();
        ui->addr_label->setText("0.0.0.0:0");
    }

    QMap<QString,agv_struct>::iterator it;
    for (it = client_map.begin(); it != client_map.end(); it++) {
        if (it.key() == agv_name) {
            ui->addr_label->setText(it.value().ip+":"+QString::number(it.value().port));
            if (it.value().state)
            {
                ui->state_label_3->setText(agv_name+" 连接中");
            }
            else{
                ui->state_label_3->setText(agv_name+" 未连接");
            }
        }
    }
}



Widget::~Widget()
{
    delete ui;
}




void Widget::on_add_button_clicked()
{
    add = new Form(this);
    add->show();
    add->move(40,110);
    connect(add,SIGNAL(send_form(QString,QString,int)),this,SLOT(from_add_agv(QString,QString,int)));
}


void Widget::on_del_button_clicked()
{
    client_map.remove(ui->agv_comboBox->currentText());
    qDebug()<< "删除：" << ui->agv_comboBox->currentText();
    ui->agv_comboBox->removeItem(ui->agv_comboBox->currentIndex());
    count--;
    ui->agv_comboBox->setCurrentIndex(0);
}

void Widget::from_add_agv(QString agv_name,QString ip,int port)
{
    agv_info.ip = ip;
    agv_info.port = port;
    if (agv_name !="" && ip !="") {
        client_map.insert(agv_name,agv_info);
        ui->agv_comboBox->addItem(agv_name);
        ui->agv_comboBox->setCurrentIndex(count);
        count++;
        qDebug()<< "添加AGV成功:" << agv_name;
    }
    else {
        qDebug()<< "添加AGV失败:" << agv_name;
    }

}


void Widget::on_clear_button_clicked()
{
    client_map.clear();
    ui->agv_comboBox->clear();
    count = 0;
}


void Widget::on_start_ctrl_move_clicked()
{
    hand_ctrl_move = true;
}


void Widget::on_stop_ctrl_move_clicked()
{
    hand_ctrl_move = false;
}


void Widget::on_charge_clicked()
{
    is_charge = false;
}


void Widget::on_stop_charge_clicked()
{
    is_charge = true;
}


void Widget::on_local_clicked()
{
    is_local = false;
}


void Widget::on_stop_local_clicked()
{
    is_local = true;
}


void Widget::on_pause_button_clicked()
{
    qDebug() << "pause_send";
    Write_modbus_tcp_Coils(0,1,"FF");
}


void Widget::on_continue_button_clicked()
{
    qDebug() << "continue_send";
    Write_modbus_tcp_Coils(1,1,"FF");
}



void Widget::on_connect_pushButton_clicked()
{
    QModbusTcpClient *client = new QModbusTcpClient();
    QString port = ui->addr_label->text().split(":")[1];

    client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,ui->addr_label->text().split(":")[0]);
    client->setConnectionParameter(QModbusDevice::NetworkPortParameter,port.toInt());
    client->connectDevice();

    Connect* t_client = new Connect(client);
    t_client->start();
    connect(t_client, SIGNAL(t_connect_send(QModbusTcpClient *)), this, SLOT(onStateChanged(QModbusTcpClient *)));
}

void Widget::onStateChanged(QModbusTcpClient *client)               //连接状态改变时的槽函数
{
    QString agv_name = ui->agv_comboBox->currentText();
    if(client->state() == QModbusDevice::ConnectedState)
    {
        qDebug() << agv_name << " 连接成功";

        QMap<QString,agv_struct>::iterator it;
        for (it = client_map.begin(); it != client_map.end(); it++) {
            if (it.key() == agv_name) {
                it.value().state = true;
                qDebug() << client;
                it.value().client = client;
                ui->state_label_3->setText(agv_name+" 连接中");
            }
        }
        ui->disconnect_pushButton->setEnabled(true);
    }

    else {
        ui->state_label_3->setText(agv_name+" 连接失败");
    }
}

QModbusTcpClient * Widget::get_agv_client()
{
    QString agv_name = ui->agv_comboBox->currentText();
    QMap<QString,agv_struct>::iterator it;
    for (it = client_map.begin(); it != client_map.end(); it++) {
        if (it.key() == agv_name) {
            return it.value().client;
        }
    }
}

bool Widget::get_agv_state()
{
    QString agv_name = ui->agv_comboBox->currentText();
    QMap<QString,agv_struct>::iterator it;
    for (it = client_map.begin(); it != client_map.end(); it++) {
        if (it.key() == agv_name) {
            return it.value().state;
        }
    }
}

void Widget::on_disconnect_pushButton_clicked()
{

    QString agv_name = ui->agv_comboBox->currentText();
    QMap<QString,agv_struct>::iterator it;
    for (it = client_map.begin(); it != client_map.end(); it++) {
        if (it.key() == agv_name)
        {
            it.value().client->disconnectDevice();
            it.value().state = false;
            it.value().client = nullptr;
            ui->state_label_3->setText(agv_name+"断开连接");
            ui->disconnect_pushButton->setEnabled(false);
        }
    }

}


void Widget::on_cancel_button_clicked()
{
    QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters,5,2);
    uint num = 50000;
    int num1 = 50000;
    writeUnit.setValue(0,num);
    writeUnit.setValue(1,num1);
//    client->sendWriteRequest(writeUnit, 1);
}


void Widget::on_station_move_clicked()
{
    QString station = ui->end_station->currentText();
    Write_modbus_tcp_HoldingRegisters(station, 0, 2);
}


bool Widget::Write_modbus_tcp_Coils(int star_add,int number,QString str1)
{
    QModbusTcpClient * client = get_agv_client();
    qDebug() << client << "写Coils数据:";
    quint16 number1 = static_cast<quint16>(number); //C++中的数据类型转换
    QModbusDataUnit writeUnit(QModbusDataUnit::Coils,star_add,number1);

    for (uint i1 = 0; i1 < writeUnit.valueCount(); i1++) {
        int j1 = 2*i1;
        QString stt = str1.mid (j1,1);
        bool ok;
        quint16 hex1 =stt.toInt(&ok,16);//将textedit中读取到的数据转换为16进制发送
        writeUnit.setValue(i1,hex1);//设置发送数据
    }

    if (auto *reply = client->sendWriteRequest(writeUnit, 1)) {// ui->spinBox_SerAddress->value()是server address   sendWriteRequest是向服务器写数据
        if (!reply->isFinished()) {   //reply Returns true when the reply has finished or was aborted.
            connect(reply, &QModbusReply::finished, this, [this, reply]() {
                if (reply->error() == QModbusDevice::ProtocolError) {
                    qDebug() << (tr("Write response error: %1 (Mobus exception: 0x%2)")
                                     .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
                                 5000);
                } else if (reply->error() != QModbusDevice::NoError) {
                    qDebug()<< (tr("Write response error: %1 (code: 0x%2)").
                                 arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
                }
                reply->deleteLater();
            });
        } else {

            reply->deleteLater();
        }
    } else {
        qDebug() << (tr("Write error: ") + client->errorString(), 5000);
        QMessageBox::information(this,"连接提示","重新连接");
        qDebug() << "重新连接:" << client;
        client->connectDevice();
    }
}


bool Widget::Write_modbus_tcp_HoldingRegisters(QString str, int star_add, int number)
{
    QModbusTcpClient * client = get_agv_client();
    qDebug() << client << "写holding数据:";
    QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters,star_add,number);
    int num1 = str.toInt();
    if (num1 > 65535)
    {
        writeUnit.setValue(0,65535);
        int num2 = num1 >> 16;
        if (num2 > 65535)
        {
            qDebug() << "超出输入范围";
        }
        else
        {
            writeUnit.setValue(1,num2);
        }
    }
    else{
        writeUnit.setValue(0,num1);
        writeUnit.setValue(1,0);
    }

    if (auto *reply = client->sendWriteRequest(writeUnit, 1)) {// ui->spinBox_SerAddress->value()是server address   sendWriteRequest是向服务器写数据
        if (!reply->isFinished()) {   //reply Returns true when the reply has finished or was aborted.
            connect(reply, &QModbusReply::finished, this, [this, reply]() {
                if (reply->error() == QModbusDevice::ProtocolError) {
                    qDebug() << (tr("Write response error: %1 (Mobus exception: 0x%2)")
                                     .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
                                 5000);
                } else if (reply->error() != QModbusDevice::NoError) {
                    qDebug()<< (tr("Write response error: %1 (code: 0x%2)").
                                 arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
                }
                reply->deleteLater();
            });
        } else {
            reply->deleteLater();
        }
    } else {
        qDebug() << (tr("Write error: ") + client->errorString(), 5000);
        QMessageBox::information(this,"连接提示","重新连接");
        qDebug() << "重新连接:" << client;
        client->connectDevice();
    }
}
